package xm.view
{
	import xm.components.ScrollableContainer;
	import xm.view.item.ViewListItemRenderer;
	
	
	/**
	 * <br> 클래스 설명 : 모바일 어플리케이션의 서브페이지</br>
	 * @author 김정환
	 */	
	public class ViewList extends ScrollableContainer 
	{
		
		//-----------------------------------------------------------------------------------
		// public vars
		//-----------------------------------------------------------------------------------
		
		public var gapBetweenItem : Number = -1;
		public var itemHeight : Number = -1;
		
		//-----------------------------------------------------------------------------------
		// protected / internal vars
		//-----------------------------------------------------------------------------------
		
		protected var data : Array = [];
		protected var itemList : Array = [];
		protected var itemGarbageList : Array = [];
		protected var RenderClass : Class;
		
		
		//-----------------------------------------------------------------------------------
		// private vars
		//-----------------------------------------------------------------------------------
		
		private var _height : Number = 0;
		
		
		//-----------------------------------------------------------------------------------
		// public functions
		//-----------------------------------------------------------------------------------
		
		/**
		 * constructor 
		 */	
		public function ViewList()
		{
			super();
		}
		
		
		
		/**
		 * commitProperties
		 */		
		override public function commitProperties():void
		{
			super.commitProperties();
			
		}
		
		/**
		 * updateDisplayList
		 */		
		override public function updateDisplayList( enforce : Boolean = false ):void
		{
			if( statusNum == -1 ) return;
			
			var len : int = data.length,
				item : ViewListItemRenderer,
				i : int = 0,
				maskWidth : Number = (useCustomViewWidth)?viewWidth:availableWidth,
				maskHeight : Number = (useCustomViewHeight)?viewHeight:availableHeight;
			
			
			//----------- 스크롤 범위보다 큰경우
			if( scrolledPosY > paddingTop ) 
			{
				len = itemList.length;
				while( i<len )
				{
					
					item = itemList[ i ] as ViewListItemRenderer;
					item.gapBetweenItem = gapBetweenItem;
					item.viewHeight = itemHeight;
					item.viewWidth = maskWidth;
					if( data[ i ] != null ) item.dataProvider = data[ i ];
					item.updateDisplayList( true );
					item.y = (itemHeight+gapBetweenItem)*i + scrolledPosY;
					
					++i;
				}
			}
			else //-------------- 스크롤범위보다 작거나 정상적인 스크롤
			{
				// 1. 전체 높이를 셋팅하고,
//				this.viewHeight = len*(itemHeight+gapBetweenItem);
				
				// 2. 리스트를 전부 비운 후.
				trashList();
				
				// 3. 스크롤 된만큼 ( 아이템의 높이+갭 )을 가지고 나눈 몫을 시작점으로 설정한다. 
				i = Math.floor( Math.abs( scrolledPosY-paddingTop )/(itemHeight+gapBetweenItem) );
				
				// 4. while 문의 length 는 시작점~ data 의 길이와, 화면의 총 리스트갯수중 적은것으로 선택한다.
				len = Math.min( len, Math.ceil((maskHeight-paddingTop-paddingBottom)/(itemHeight+gapBetweenItem) )+i+1 );
				
				// 5. 렌더링한다.
				while( i<len )
				{
					if( i > itemList.length - 1 )
					{
						item = getItem();
					}
					else
					{
						item = itemList[ i ] as ViewListItemRenderer;
					}
					
					item.viewHeight = itemHeight;
					item.viewWidth = maskWidth;
					
					item.dataProvider = data[ i ];
					item.updateDisplayList( true );
					itemList.push( item );
					addChildAt( item, 1 );
					
					item.y = (itemHeight+gapBetweenItem)*i + scrolledPosY;
					
					++i;
				}
				
			}
			
			// 6. 부모에서 스크롤바 설정하면 끝.
			super.updateDisplayList(enforce);
		}
		
		
		
		
		
		
		//-----------------------------------------------------------------------------------
		// life cycle functions
		//-----------------------------------------------------------------------------------
		
		/**
		 * createChildren
		 */		
		override public function createChildren():void
		{
			super.createChildren();
			
		}
		
		
		/**
		 * createComplete
		 */		
		override public function creationComplete():void
		{
			super.creationComplete();
			
		}
		
		
		/**
		 * add
		 */		
		override public function add():void
		{
			super.add();
			
		}
		
		
		/**
		 * remove
		 */		
		override public function remove():void
		{
			super.remove();
		}
		
		
		/**
		 * destroy
		 */		
		override public function destroy():void
		{
			
			var i:int, len : int, item : ViewListItemRenderer;
			
			gapBetweenItem = NaN;
			itemHeight = NaN;
			_height = NaN;
			RenderClass = null;
			
			
			i=0;
			len=data.length;
			while( i<len )
			{
				delete data[ i ];
				++i;
			}
			data = null;
			
			
			
			i=0;
			len = itemGarbageList.length;
			while( i<len )
			{
				item = itemGarbageList[ i ]  as ViewListItemRenderer;
				item.destroy();
				item = null;
				delete itemGarbageList[ i ];
				
				++i;
			}
			itemGarbageList = null;
			
			
			i=0;
			len = itemList.length;
			while( i<len )
			{
				item = itemList[ i ]  as ViewListItemRenderer;
				item.destroy();
				item = null;
				delete itemList[ i ];
				
				++i;
			}
			itemList = null;
			
			
			super.destroy();
			
		}
		
		//-----------------------------------------------------------------------------------
		// setter / getter
		//-----------------------------------------------------------------------------------
		
		/**
		 * @param IR : Class extends ViewListItemRenderer 
		 */		
		public function set itemRenderer( IR : Class ):void
		{
			RenderClass = IR;
		}
		
		/**
		 * @param _data
		 */		
		public function set dataProvider( _data : Array ):void
		{
			if( gapBetweenItem == -1 || itemHeight == -1 )
			{
				trace("View List [ dataProvider ] Error : gapBetweenItem, itemHeight 를 먼저 설정해 주세요.");
				throw new Error( "View List [ dataProvider ] Error : gapBetweenItem, itemHeight 를 먼저 설정해 주세요." );
				return;
			}
			
			this.data = _data;
			scrolledPosY = paddingTop;
			height = data.length*(itemHeight+gapBetweenItem);
		}
		
		/**
		 * @return  dataProvider : Array
		 */		
		public function get dataProvider():Array
		{
			return data;
		}
		
		
		
		/**
		 * @param value : Number
		 */		
		override public function set height( value : Number ):void
		{
			_height = value;
		}
		
		
		/**
		 * list 에서는 this의 높이를 가상으로 셋팅해야 한다.
		 * @return this의 높이 
		 */		
		override public function get height():Number
		{
			return _height;
		}
		//-----------------------------------------------------------------------------------
		// protected functions
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		// internal functions
		//-----------------------------------------------------------------------------------
		
		
		
		
		//-----------------------------------------------------------------------------------
		// private functions
		//-----------------------------------------------------------------------------------
		
		
		// 리스트 비우기
		private function trashList():void
		{
			var i:int = -1,
				len : int = itemList.length,
				item : ViewListItemRenderer;
			
			while( ++i<len )
			{
				item = itemList.pop() as ViewListItemRenderer;
				if( item && item.parent ) item.parent.removeChild( item );
				itemGarbageList.push( item );
			}
		}
		
		// 리스트 아이템 재활용.
		private function getItem():ViewListItemRenderer
		{
			if( RenderClass == null )
			{
				throw new Error( "RenderClass 가 정의되지 않았습니다. itemRenderer 를 등록해주세요." );
				return;
			}
			
			var item : ViewListItemRenderer;
			if( itemGarbageList.length > 0 )
			{
				item = itemGarbageList.pop() as ViewListItemRenderer;
			}
			else
			{
				item = new RenderClass();
			}
			
			return item as ViewListItemRenderer;
		}		
		
		
		//-----------------------------------------------------------------------------------
		// event handler
		//-----------------------------------------------------------------------------------
		
		
		
		
		
		
		
		
		
	}
}